package com.yuehuanghun.admin.core.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yuehuanghun.admin.core.config.UserConstants;
import com.yuehuanghun.admin.core.config.constant.CacheKeys;
import com.yuehuanghun.admin.core.domain.SysDictData;
import com.yuehuanghun.admin.core.domain.SysDictType;
import com.yuehuanghun.admin.core.mapper.SysDictDataMapper;
import com.yuehuanghun.admin.core.mapper.SysDictTypeMapper;
import com.yuehuanghun.admin.core.service.ISysDictTypeService;
import com.yuehuanghun.framework.exception.BizException;
import com.yuehuanghun.framework.util.StringUtils;
import com.yuehuanghun.mybatis.milu.ext.BaseServiceImpl;

/**
 * 字典 业务层处理
 * 
 * @author yadmin
 */
@Service
@DependsOn("dictUtils")
public class SysDictTypeServiceImpl extends BaseServiceImpl<SysDictType, Long, SysDictTypeMapper> implements ISysDictTypeService {
	@Autowired
	private SysDictDataMapper dictDataMapper;
	
	@Autowired
	private CacheManager cacheManager;

	/**
	 * 项目启动时，初始化字典到缓存，预热
	 */
	@PostConstruct
	public void init() {
		List<SysDictType> dictTypeList = domainMapper.findAll();
		for (SysDictType dictType : dictTypeList) {
			List<SysDictData> dictDatas = dictDataMapper.findByDictType(dictType.getDictType());
			cacheManager.getCache(CacheKeys.SYS_DICT).put(dictType.getDictType(), dictDatas);
		}
	}

	/**
	 * 根据所有字典类型
	 * 
	 * @return 字典类型集合信息
	 */
	@Override
	public List<SysDictType> getDictTypeAll() {
		return domainMapper.findAll();
	}

	/**
	 * 根据字典类型查询字典数据
	 * 
	 * @param dictType 字典类型
	 * @return 字典数据集合信息
	 */
	@Override
	@Cacheable(cacheNames = CacheKeys.SYS_DICT, key = "#p0")
	public List<SysDictData> getDictDataByType(String dictType) {
		return dictDataMapper.findByDictType(dictType);
	}

	/**
	 * 根据字典类型ID查询信息
	 * 
	 * @param dictId 字典类型ID
	 * @return 字典类型
	 */
	@Override
	public SysDictType getDictTypeById(Long dictId) {
		return domainMapper.findById(dictId).orElseThrow(() -> new BizException("字典不存在"));
	}

	/**
	 * 根据字典类型查询信息
	 * 
	 * @param dictType 字典类型
	 * @return 字典类型
	 */
	@Override
	public SysDictType getDictTypeByType(String dictType) {
		return domainMapper.findFirstByDictType(dictType);
	}

	/**
	 * 批量删除字典类型信息
	 * 
	 * @param dictIds 需要删除的字典ID
	 * @return 结果
	 */
	@Override
	public int deleteDictTypeByIds(Long[] dictIds) {
		List<String> dictTypeList = new ArrayList<>(dictIds.length);
		for (Long dictId : dictIds) {
			SysDictType dictType = getDictTypeById(dictId);
			if (dictDataMapper.countByDictType(dictType.getDictType()) > 0) {
				throw new BizException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
			}
			dictTypeList.add(dictType.getDictType());
		}
		int count = domainMapper.deleteByIds(Arrays.asList(dictIds));
		if (count > 0) {
			dictTypeList.forEach(dictType -> {
				cacheManager.getCache(CacheKeys.SYS_DICT).evict(dictType);
			});
		}
		return count;
	}

	/**
	 * 清空缓存数据
	 */
	@Override
	@CacheEvict(cacheNames = CacheKeys.SYS_DICT, allEntries = true)
	public void clearCache() {
		//没有操作，靠切面清空缓存
	}

	/**
	 * 新增保存字典类型信息
	 * 
	 * @param dictType 字典类型信息
	 * @return 结果
	 */
	@Override
	@CacheEvict(cacheNames = CacheKeys.SYS_DICT, key = "#p0.dictType")
	public int insertDictType(SysDictType dictType) {
		return domainMapper.insert(dictType);
	}

	/**
	 * 修改保存字典类型信息
	 * 
	 * @param dictType 字典类型信息
	 * @return 结果
	 */
	@Override
	@Transactional
	@CacheEvict(cacheNames = CacheKeys.SYS_DICT, key = "#p0.dictType")
	public int updateDictType(SysDictType dictType) {
		SysDictType oldDict = domainMapper.findById(dictType.getDictId())
				.orElseThrow(() -> new BizException("字典不存在"));
		SysDictData updateData = new SysDictData();
		updateData.setDictType(dictType.getDictType());
		dictDataMapper.updateByLambdaCriteria(updateData, p -> p.eq(SysDictData::getDictType, oldDict.getDictType()));
		return domainMapper.updateById(dictType);
	}

	/**
	 * 校验字典类型称是否唯一
	 * 
	 * @param dict 字典类型
	 * @return 结果
	 */
	@Override
	public String checkDictTypeUnique(SysDictType dict) {
		Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
		SysDictType dictType = domainMapper.findFirstByDictType(dict.getDictType());
		if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
			return UserConstants.NOT_UNIQUE;
		}
		return UserConstants.UNIQUE;
	}
	
    @Override
	@CacheEvict(cacheNames = CacheKeys.SYS_DICT, key = "#p0.dictType")
    public void reloadDictCache(String dictType) {
    	//没有操作，靠切面清空缓存
    }
}
